
#include <assert.h>
#include <fs/filestd.h>
#include <stdlib.h>
#include <string.h>

ceFileStd::ceFileStd()
	: _file(0)
	, _read(false)
	, _write(false)
{
  CE_OBJECT_CONSTR;
}

ceFileStd::~ceFileStd ()
{
	if (_file)
		{
			fclose (_file);
		}
}

bool ceFileStd::Open(const char *filename, ceOpenMode mode, ceTextMode textMode)
{
	switch (mode)
		{
		case OM_Read:

			_file = fopen (filename, textMode == TM_Text ? "rt" : "rb");
			_read = true;
			break;
		case OM_Write:
			_file = fopen (filename, textMode == TM_Text ? "wt" : "wb");
			_write = true;
			break;
		case OM_ReadWrite:
			_file = fopen (filename, textMode == TM_Text ? "a+t" : "a+b");
			_read = true;
			_write = true;
			break;
    default:
      printf ("ceFileStd::Open: Unsupported openmode: %d\n", mode);
      return false;
		}

  if (!_file)
    {
      printf ("ceFileStd::Open: File %s no found\n", filename); fflush (stdout);
      return false;
    }

  _location = "";
  _name = "";
  _extension = "";
  char* tmpname = strdup(filename);

  char* locptr = tmpname;
  char* extptr = 0;
  char* nameptr = 0;
  for (int i=strlen(tmpname)-1; i>=0; --i)
    {
      char c = tmpname[i];
      if (c == '.')
        {
          if (!extptr)
            {
              tmpname[i] = 0;
              extptr = tmpname + i + 1;
            }
          }
      else if (c == '/' || c == '\\')
        {
          tmpname [i] = 0;
          nameptr = tmpname + i + 1;
          break;
        }
    }
   
	if (locptr)
    {
      _location   = locptr;
		}
	if (nameptr)
		{
      _name       = nameptr;
		}
	if (extptr)
		{
      _extension  = extptr;
    }

  free (tmpname);

  return true;
}

bool ceFileStd::IsOpen() const
{
	return _file != 0;
}

bool ceFileStd::Close()
{
	assert (_file);
	fclose (_file);
	_file = 0;
	return true;
}


bool ceFileStd::IsRandomAccess() const
{
	return true;
}

bool ceFileStd::IsReadable() const
{
	return _read;
}

bool ceFileStd::IsWritable() const
{
	return _write;
}

bool ceFileStd::Seek(ceSeekPos pos, long num)
{
	assert (_file);
	int sm = 0;
	switch (pos)
		{
		case SP_Current:
			sm = SEEK_CUR;
			break;
		case SP_Set:
			sm = SEEK_SET;
			break;
		case SP_End:
			sm = SEEK_END;
			break;
		default:
			return false;
		}
	fseek (_file, num, sm);

	return true;
}

long ceFileStd::Tell()
{
	assert (_file);
	return ftell (_file);
}

long ceFileStd::GetLength()
{
	long cp = Tell();
	Seek (SP_End, 0);
	long size = Tell ();
	Seek (SP_Set, cp);
	return size;
}

long ceFileStd::Read(void *buffer, long size)
{
	assert (_file);
	return fread (buffer, sizeof(char), size, _file);
}

long ceFileStd::Write(const void *buffer, long size)
{
	assert (_file);
	return fwrite (buffer, sizeof(char), size, _file);
}

const std::string& ceFileStd::GetExtension () const
{
  return _extension;
}

const std::string& ceFileStd::GetName () const
{
  return _name;
}


const std::string& ceFileStd::GetLocation () const
{
  return _location;
}
